﻿using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Media.Animation;
using Bling.DSL;
using Bling.Properties;
using Bling.Animation;
using Bling.WPF;
using Bling.Shapes;
using Bling.Slides;
using Bling.Util;
using Bling.Linq;
using Bling.Lighting;
using Bling.Physics;

namespace Presentation {
  public class MismatchTest : Canvas {
    public class MyValueConverter : IMultiValueConverter {
      public object Convert(object[] values, Type targetType, 
        object parameter, System.Globalization.CultureInfo culture) {
        return ((double)values[0]) + ((double)values[1]);
      }
      public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
        throw new NotSupportedException();
      }
    }
    public MismatchTest() {
      FrameworkElement widgetA = null;
      FrameworkElement widgetB = null;
      FrameworkElement widgetC = null;
      MultiBinding B = new MultiBinding();
      B.Bindings.Add(new Binding() { Path = new PropertyPath(WidthProperty), Source = widgetB });
      B.Bindings.Add(new Binding() { Path = new PropertyPath(WidthProperty), Source = widgetC });
      B.Converter = new MyValueConverter();
      widgetA.SetBinding(WidthProperty, B);
    }

  }


  public class Mismatch : Canvas {
    public static readonly ImageSourceBl BindingAImage = (new BitmapImage("Resources/bindingA.PNG".MakePackUri(typeof(Mismatch))));
    public static readonly ImageSourceBl BindingBImage = (new BitmapImage("Resources/bindingB.PNG".MakePackUri(typeof(Mismatch))));
    public Mismatch() {
      CanvasBl Canvas = new CanvasBl(this) { CenterPosition = this.Bl().CenterSize };
      PointBl Size0 = new PointBl(0, 0);
      var l0 = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, 0),
        Content = "Mismatch between Language Constructs",
        Font = { Size = 60d, Weight = FontWeights.SemiBold },
      };
      Size0 = l0.RightBottom.Max(Size0);

      var l1 = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, l0.Bottom),
        Content = "and Declarative UI Abstractions",
        Font = l0.Font, 
      };
      Size0 = l1.RightBottom.Max(Size0);
      var l2 = new LabelBl(Canvas) {
        LeftTop = new PointBl(l0.Left.Min(l1.Left), l1.Bottom),
        Content = "Verbosity: lots of code to express simple relationships",
        Font = { Size = 40d, Weight = FontWeights.SemiBold, Brush = Brushes.DarkGreen },
      };
      Size0 = l2.RightBottom.Max(Size0);


      var imageA = new ImageBl(Canvas) {
        Source = BindingAImage, 
        LeftTop = l2.LeftBottom,
        Size = BindingAImage.Size * 1.5d,
      };
      Size0 = imageA.RightBottom.Max(Size0);

      var l2a = new LabelBl(Canvas) {
        LeftTop = imageA.LeftBottom,
        Content = "Hand written boilerplate",
        Font = l2.Font, 
      };
      Size0 = new PointBl(l2a.Width,l2a.Bottom).Max(Size0);

      var imageB = new ImageBl(Canvas) {
        Source = BindingBImage,
        LeftTop = new PointBl(imageA.Right, l1.Bottom),
        Size = BindingBImage.Size * 1.5d,
      };
      var l3 = new LabelBl(Canvas) {
        Font = l2.Font, LeftTop = imageB.LeftBottom,
        Content = "Safety: lack of static checking even with static info",
      };
      Size0 = new PointBl(l3.Width, l3.Bottom).Max(Size0);
      var l4 = new LabelBl(Canvas) {
        Font = l2.Font, LeftTop = l3.LeftBottom,
        Content = "Poor reusability of boilerplate",
      };
      Size0 = new PointBl(l4.Width, l4.Bottom).Max(Size0);

      imageA.OnMouseDown = (image, xxx) => {
        l2.Left.Animate.To = -imageA.Width;
        return true;
      };
      imageB.OnMouseDown = (image, xxx) => {
        l2.Left.Animate.To = 0;
        return true;
      };
      Canvas.Size = Size0;
      Canvas.ScaleTo = this.Bl().Size;
      
    }

  }
  public class SolutionA : Canvas {
    public SolutionA() {
      CanvasBl Canvas = new CanvasBl(this) { CenterPosition = this.Bl().CenterSize };
      PointBl Size0 = new PointBl(0, 0);

      var l0 = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, Size0.Y),
        Font = { Size = 60d, Weight = FontWeights.SemiBold },
        Content = "Solution A",
      };
      Size0 = Size0.Max(l0.RightBottom);
      var l0b = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, Size0.Y),
        Font = { Size = 40d, Weight = FontWeights.SemiBold, Brush = Brushes.DarkOrange },
        Content = "High vs. low-level declarative constructs",
      };
      Size0 = Size0.Max(l0b.RightBottom);

      var l1 = new LabelBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Font = { Size = 40d, Weight = FontWeights.SemiBold, Brush = Brushes.DarkGreen },
        Content = "Layout managers/panels: stack, grid, list, wrap, dock...",
      };
      Size0 = Size0.Max(l1.RightBottom);

      var l2 = new LabelBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Font = l1.Font,
        Content = "Styles, triggers, templates, storyboards...",
      };
      Size0 = Size0.Max(l2.RightBottom);
      
      var l4 = new LabelBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Font = l2.Font,
        Content = "Very big API problem",
      };
      l4.Foreground = Brushes.DarkRed;
      Size0 = Size0.Max(l4.RightBottom);

      Canvas.Size = Size0;
      Canvas.ScaleTo = this.Bl().Size - new PointBl(10, 10);
    }

  }
  public class SolutionB : AnimatedCanvas {
    public SolutionB() {
      CanvasBl Canvas = new CanvasBl(this) { CenterPosition = this.Bl().CenterSize };
      PointBl Size0 = new PointBl(0, 0);

      var l0 = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, Size0.Y),
        Font = { Size = 60d, Weight = FontWeights.SemiBold },
        Content = "Solution B",
      };
      Size0 = Size0.Max(l0.RightBottom);
      var l0b = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, Size0.Y),
        Font = { Size = 40d, Weight = FontWeights.SemiBold, Brush = Brushes.DarkOrange },
        Content = "Standalone UI language; e.g., JavaFX",
      };
      Size0 = Size0.Max(l0b.RightBottom);

      var l1 = new LabelBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Font = { Size = 40d, Weight = FontWeights.SemiBold, Brush = Brushes.DarkGreen },
        Content = "Special “bind” and animation syntax",
      };
      Size0 = Size0.Max(l1.RightBottom);

      var i0 = new ImageBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Source = new BitmapImage("Resources/javafxBind.PNG".MakePackUri(typeof(Mismatch))),
      };
      Size0 = Size0.Max(i0.RightBottom);
      var i1 = new ImageBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Source = new BitmapImage("Resources/javafxBindB.PNG".MakePackUri(typeof(Mismatch))),
      };
      Size0 = Size0.Max(i1.RightBottom);


      var l2 = new LabelBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Font = l1.Font,
        Foreground = Brushes.DarkRed,
        Content = "Expensive, risky",
      };
      Size0 = Size0.Max(l2.RightBottom);

      Canvas.Size = Size0;
      Canvas.ScaleTo = this.Bl().Size - new PointBl(10, 10);
    }
  }
  public class SolutionC : Canvas {
    public SolutionC() {
      RightSizeCanvasBl Canvas = new RightSizeCanvasBl(this) { CenterPosition = this.Bl().CenterSize };
      var l0 = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, Canvas.AtSize.Y),
        Font = { Size = 60d, Weight = FontWeights.SemiBold },
        Content = "Solution C",
      };
      var l0b = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, Canvas.AtSize.Y),
        Font = { Size = 40d, Weight = FontWeights.SemiBold, Brush = Brushes.DarkOrange },
        Content = "Dependent UI DSLs; e.g., XAML, HLSL",
      };
      var sz = Canvas.AtSize.Y;

      var Canvas0 = new RightSizeCanvasBl((CanvasBl) Canvas) {
        LeftTop = new PointBl(0, Canvas.AtSize.Y),
        Children = {

        },
      };
      var l1 = new LabelBl(Canvas0) {
        LeftTop = new PointBl(0, Canvas0.AtSize.Y),
        Font = { Size = 40d, Weight = FontWeights.SemiBold, Brush = Brushes.DarkGreen },
        Content = "* Langauge switching is user unfriendly",
      };
      // pic of XAML code behind.
      var l2 = new LabelBl(Canvas0) {
        LeftTop = new PointBl(0, Canvas0.AtSize.Y),
        Font = l1.Font,
        Content = "* Still kind of expensive",
      };

      var Canvas1 = new RightSizeCanvasBl((CanvasBl)Canvas) {
        LeftTop = Canvas0.RightTop,
      };


      // Add HLSL pics.
      Canvas.ScaleTo = this.Bl().Size - new PointBl(10, 10);

    }

  }
  public class ExampleC : Canvas {
    public ExampleC() {
      CanvasBl Canvas = new CanvasBl(this) { CenterPosition = this.Bl().CenterSize };
      PointBl Size0 = new PointBl(0, 0);

      var l0 = new LabelBl(Canvas) {
        CenterTop = new PointBl(Canvas.CenterSize.X, Size0.Y),
        Font = { Size = 60d, Weight = FontWeights.SemiBold },
        Content = "WPF Pixel Shaders",
      };
      Size0 = Size0.Max(l0.RightBottom);

      var i0 = new ImageBl(Canvas) {
        LeftTop = new PointBl(0, Size0.Y),
        Source = new BitmapImage("Resources/hlsl.PNG".MakePackUri(typeof(Mismatch))),
      };
      var i05 = new ImageBl(Canvas) {
        LeftTop = i0.RightTop,
        Source = new BitmapImage("Resources/Warp.PNG".MakePackUri(typeof(Mismatch))),
      };
      var stepA = i0.Width + i05.Width;
      Size0 = Size0.Max(new PointBl(stepA, i0.Bottom));
      i0.OnMouseDown = (x, y) => {
        i0.Left.Animate.To = stepA * -1d;
        return true;
      };

      var i1 = new ImageBl(Canvas) {
        LeftTop = i05.RightTop,
        Source = new BitmapImage("Resources/boilerTop.PNG".MakePackUri(typeof(Mismatch))),
      };
      Size0 = Size0.Max(new PointBl(i1.Width, i1.Bottom));
      var stepB = stepA + i1.Width;
      i1.OnMouseDown = (x, y) => {
        i0.Left.Animate.To = stepB * -1d;
        return true;
      };

      var i2 = new ImageBl(Canvas) {
        LeftTop = i1.RightTop,
        Source = new BitmapImage("Resources/boilerCenter.PNG".MakePackUri(typeof(Mismatch))),
      };
      Size0 = Size0.Max(new PointBl(i2.Width, i2.Bottom));
      var stepC = stepB + i2.Width;

      i2.OnMouseDown = (x, y) => {
        i0.Left.Animate.To = stepC * -1d;
        return true;
      };

      var i3 = new ImageBl(Canvas) {
        LeftTop = i2.RightTop,
        Source = new BitmapImage("Resources/boilerBot.PNG".MakePackUri(typeof(Mismatch))),
      };
      Size0 = Size0.Max(new PointBl(i3.Width, i3.Bottom));
      i3.OnMouseDown = (x, y) => {
        i0.Left.Animate.To = 0;
        return true;
      };

      Canvas.Size = Size0;
      Canvas.ScaleTo = this.Bl().Size - new PointBl(10, 10);
    }
  }
}
